#ifndef _THREAD_HPP_
#define _THREAD_HPP_

#include <iostream>
#include <string>
#include <memory>
#include <cstdio>
#include <cstring>
// zdl: -pthread 库
#include <pthread.h>
#include <unistd.h>
#include <functional>



namespace threadModule
{

    // zdl: 这里我们使用 std::function 来定义线程函数的类型
    // template<class T = void>
    using func_t = std::function<void(std::string name)>;

    static int number = 1;

    enum class ThreadState
    {
        New,
        Running,
        Stop
    };

    class Thread
    {

    private:
        static void *routine(void *args) // 这里有一个重要的一步，
        // 就是我们需要解决两个参数的问题，写在类里面就有两个参数，this指针，现在我们就直接
        // 使用static 解决船队u参数有两个的问题，
        // zdl:: 但是i现在我们想要使用类里面的变量该怎么办呢？
        // zdl:: 直接传递 this 指针为参数就好了
        {
            auto t = static_cast<Thread *>(args);
            // 这里可以使用类里面的变量
            t->_state = ThreadState::Running; // 设置线程状态为开始
            t->_func(t->_name);                       // 调用线程函数
            return nullptr;
        }
        void enableJoinable()
        {
            _joinable = false;
        }

    public:
        Thread(func_t func) : _func(func)
        {
            _name = "Thread-" + std::to_string(number++);
            _pid = ::getpid(); // 获取当前进程的pid
        }
        ~Thread()
        {
        }
        void Running()
        {
            if (_state != ThreadState::Running)
            {
                pthread_create(&_tid, nullptr, routine, this);
                _state = ThreadState::Running;
                // (void)n; // 忽略返回值
            }
        }

        bool stop()
        {
            if (_state != ThreadState::Running)
            {

                int n = ::pthread_cancel(_tid);
                std::cout << "pthread_cancel start!" << std::endl;
                if (n != 0)
                    return false;
                _state = ThreadState::Stop; // 设置线程状态为停止
                return true;
            }
            return false;
        }

        bool join()
        {
            if (_joinable)
            {
                int n = pthread_join(_tid, nullptr);
                if (n != 0)
                    return false;
                _state = ThreadState::Stop; // 设置线程状态为停止
                return true;
            }

            return false; // 如果线程不可join，返回false
        }
        void enableDetach()
        {
        }

        void detach()
        {
            enableJoinable();
            int n = pthread_detach(_tid);
            (void)n; // 忽略返回值
        }
        bool idJoinable() const
        {
            return _joinable;
        }

        // get 接口
        std::string getName() const
        {
            return _name;
        }
        pthread_t getTid() const
        {
            return _tid;
        }
        pid_t getPid() const
        {
            return _pid;
        }
    private:
        std::string _name;
        pthread_t _tid;
        pid_t _pid;
        bool _joinable = false;                // 是否可以join
        func_t _func;                          // 线程函数
        ThreadState _state = ThreadState::New; // 线程状态

        // 可传入的参数
    };
}

#endif

// namespace threadModule
// {

//     // zdl: 这里我们使用 std::function 来定义线程函数的类型
//     template<class T = void>
//     using func_t = std::function<void(T)>;

//     static int number = 1;

//     enum class ThreadState
//     {
//         New,
//         Running,
//         Stop
//     };
//     template<class T>
//     class Thread
//     {

//     private:
//         static void *routine(void *args) // 这里有一个重要的一步，
//         // 就是我们需要解决两个参数的问题，写在类里面就有两个参数，this指针，现在我们就直接
//         // 使用static 解决船队u参数有两个的问题，
//         // zdl:: 但是i现在我们想要使用类里面的变量该怎么办呢？
//         // zdl:: 直接传递 this 指针为参数就好了
//         {
//             auto t = static_cast<Thread<T> *>(args);
//             // 这里可以使用类里面的变量
//             t->_state = ThreadState::Running; // 设置线程状态为开始
//             t->_func(t->_data);                       // 调用线程函数
//             return nullptr;
//         }
//         void enableJoinable()
//         {
//             _joinable = false;
//         }

//     public:
//         Thread(func_t<T> func, T data) : _func(func), _data(data)
//         {
//             _name = "Thread-" + std::to_string(number++);
//             _pid = ::getpid(); // 获取当前进程的pid
//         }
        
//         ~Thread()
//         {
//         }
//         void Running()
//         {
//             if (_state != ThreadState::Running)
//             {
//                 pthread_create(&_tid, nullptr, routine, this);
//                 _state = ThreadState::Running;
//                 // (void)n; // 忽略返回值
//             }
//         }

//         bool stop()
//         {
//             if (_state != ThreadState::Running)
//             {

//                 int n = ::pthread_cancel(_tid);
//                 std::cout << "pthread_cancel start!" << std::endl;
//                 if (n != 0)
//                     return false;
//                 _state = ThreadState
//                 ::Stop; // 设置线程状态为停止
//                 return true;
//             }
//             return false;
//         }

//         bool join()
//         {
//             if (_joinable)
//             {
//                 int n = pthread_join(_tid, nullptr);
//                 if (n != 0)
//                     return false;
//                 _state = ThreadState::Stop; // 设置线程状态为停止
//                 return true;
//             }
//             return false; // 如果线程不可join，返回false
//         }
//         void enableDetach()
//         {
//         }

//         void detach()
//         {
//             enableJoinable();
//             int n = pthread_detach(_tid);
//             (void)n; // 忽略返回值
//         }
//         bool idJoinable() const
//         {
//             return _joinable;
//         }

//         // get 接口
//         std::string getName() const
//         {
//             return _name;
//         }
//         pthread_t getTid() const
//         {
//             return _tid;
//         }
//         pid_t getPid() const
//         {
//             return _pid;
//         }
//     private:
//         std::string _name;
//         pthread_t _tid;
//         pid_t _pid;
//         bool _joinable = false;                // 是否可以join
//         func_t<T> _func;                          // 线程函数
//         ThreadState _state = ThreadState::New; // 线程状态

//         // 可传入的参数
//         T _data;
//     };
// }

// #endif
